<template>
  <el-card class="products-page">
    <!-- 工具栏 -->
    <div class="toolbar">
      <!-- 名称搜索 -->
      <el-input
        v-model="filters.name"
        placeholder="商品名称"
        clearable
        @clear="onSearch"
        @keyup.enter="onSearch"
        size="small"
        class="toolbar-item"
      >
        <template #prefix>
          <el-icon><Search /></el-icon>
        </template>
      </el-input>
      <!-- 状态 -->
      <el-select
        v-model="filters.status"
        placeholder="状态"
        clearable
        @change="onSearch"
        size="small"
        class="toolbar-item"
        style="width: 120px"
      >
        <el-option label="启用" :value="1" />
        <el-option label="禁用" :value="0" />
      </el-select>
      <!-- 门店筛选 -->
      <el-select
        v-model="filters.storeId"
        placeholder="门店"
        clearable
        filterable
        @change="onSearch"
        size="small"
        class="toolbar-item"
        style="width: 180px"
      >
        <el-option
          v-for="s in stores"
          :key="s.id"
          :label="s.name"
          :value="s.id"
        />
      </el-select>
      <!-- 分类筛选 -->
      <el-cascader
        v-model="filters.categoryPath"
        :options="categoryOptions"
        placeholder="分类"
        clearable
        filterable
        @change="onCategoryChange"
        size="small"
        class="toolbar-item"
        style="width: 200px"
      />
      <!-- 品牌筛选 -->
      <el-select
        v-model="filters.brandId"
        placeholder="品牌"
        clearable
        filterable
        @change="onSearch"
        size="small"
        class="toolbar-item"
        style="width: 180px"
      >
        <el-option
          v-for="b in brands"
          :key="b.id"
          :label="b.name"
          :value="b.id"
        />
      </el-select>

      <el-button type="primary" size="small" @click="onSearch">查询</el-button>

      <div class="toolbar-actions">
        <el-tooltip content="刷新数据" effect="dark">
          <el-button type="primary" size="small" circle @click="onRefresh">
            <el-icon><Refresh /></el-icon>
          </el-button>
        </el-tooltip>
        <el-tooltip content="新增商品" effect="dark">
          <el-button type="primary" size="small" circle @click="openDialog()">
            <el-icon><Plus /></el-icon>
          </el-button>
        </el-tooltip>
        <el-tooltip content="批量删除" effect="dark">
          <el-button
            type="danger"
            size="small"
            circle
            :disabled="!multipleSelection.length"
            @click="onBatchDelete"
          >
            <el-icon><Delete /></el-icon>
          </el-button>
        </el-tooltip>
        <el-tooltip content="批量操作" effect="dark">
          <el-dropdown @command="handleBatchCommand">
            <el-button type="primary" size="small">
              批量操作<el-icon class="el-icon--right"><ArrowDown /></el-icon>
            </el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="enable">批量启用</el-dropdown-item>
                <el-dropdown-item command="disable">批量禁用</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </el-tooltip>
        <!-- 新增：下载模板、导入、导出按钮 -->
        <el-button size="small" @click="downloadTemplate">下载模板</el-button>
        <el-upload
          class="upload-demo"
          :before-upload="beforeImport"
          :show-file-list="false"
        >
          <el-button size="small">导入</el-button>
        </el-upload>
        <el-dropdown @command="handleExportCommand">
          <el-button size="small">
            导出<el-icon class="el-icon--right"><ArrowDown /></el-icon>
          </el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="excel">导出Excel</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <el-tooltip content="列设置" effect="dark">
          <el-button size="small" circle @click="showColumnSettings">
            <el-icon><Setting /></el-icon>
          </el-button>
        </el-tooltip>
      </div>
    </div>

    <!-- 表格 -->
    <div class="table-wrapper">
      <el-table
        v-loading="loading"
        :data="products"
        stripe
        border
        highlight-current-row
        @selection-change="onSelectChange"
        :max-height="600"
        style="width: 100%"
        :scrollbar-always-on="true"
        row-key="id"
        :resizable="true"
        :default-sort="{ prop: 'createdAt', order: 'descending' }"
        @sort-change="onSortChange"
      >
        <!-- 固定在左侧的列 -->
        <el-table-column align="center" type="selection" width="55" fixed="left" />
        <el-table-column align="center" prop="id" label="ID" width="60" fixed="left" />
        <el-table-column
          v-if="visibleColumns.includes('storeName')"
          prop="storeName"
          label="门店"
          align="center"
          min-width="120"
          sortable
        />
        <!-- 中间可滚动的列 -->
        <el-table-column
          v-if="visibleColumns.includes('categoryName')"
          prop="categoryName"
          label="分类"
          align="center"
          min-width="120"
          sortable
        />
        <el-table-column
          v-if="visibleColumns.includes('brand')"
          prop="brand"
          label="品牌"
          align="center"
          min-width="120"
          sortable
        />
        <el-table-column
          v-if="visibleColumns.includes('name')"
          prop="name"
          label="商品名称"
          align="center"
          min-width="200"
          sortable
        />
        <el-table-column
          v-if="visibleColumns.includes('spuTitle')"
          prop="spuTitle"
          label="SPU"
          align="center"
          min-width="150"
          sortable
        >
          <template #default="{ row }">
            <el-tag v-if="row.spuTitle" type="info">{{ row.spuTitle }}</el-tag>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column
          v-if="visibleColumns.includes('mainImage')"
          label="主图"
          width="120"
          align="center"
        >
          <template #default="{ row }">
            <el-image
              :src="row.mainImage"
              style="width: 60px; height: 60px"
              fit="contain"
              :preview-src-list="[row.mainImage]"
              :initial-index="0"
              preview-teleported
            />
          </template>
        </el-table-column>
        <el-table-column
          v-if="visibleColumns.includes('status')"
          label="状态"
          width="100"
          align="center"
        >
          <template #default="{ row }">
            <el-switch
              v-model="row.status"
              :active-value="1"
              :inactive-value="0"
              @change="(val) => onToggleStatus(row, val)"
              size="small"
            />
          </template>
        </el-table-column>
        <el-table-column
          v-if="visibleColumns.includes('createdAt')"
          align="center"
          prop="createdAt"
          label="创建时间"
          min-width="180"
          sortable
        />
        <!-- 固定在右侧的列 -->
        <el-table-column align="center" label="操作" width="180" fixed="right">
          <template #default="{ row }">
            <div class="action-btns">
              <el-tooltip content="编辑" effect="dark">
                <el-button
                  type="primary"
                  :icon="Edit"
                  circle
                  @click="openDialog(row)"
                />
              </el-tooltip>
              <el-tooltip content="标签" effect="dark">
                <el-button
                  type="success"
                  :icon="PriceTag"
                  circle
                  @click="openTagDialog(row)"
                />
              </el-tooltip>
              <el-tooltip content="删除" effect="dark">
                <el-button
                  type="danger"
                  :icon="Delete"
                  circle
                  @click="onDelete(row)"
                />
              </el-tooltip>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 分页 -->
    <div class="pagination">
      <el-pagination
        background
        layout="prev, pager, next, jumper, sizes, total"
        :current-page="pageNum"
        :page-size="pageSize"
        :page-sizes="[10, 20, 50]"
        :total="total"
        @current-change="onPageChange"
        @size-change="onSizeChange"
      />
    </div>

    <!-- 新增/编辑 弹窗 -->
    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="600px">
      <el-form
        :model="form"
        :rules="formRules"
        ref="formRef"
        label-width="100px"
      >
        <!-- 门店 -->
        <el-form-item label="门店" prop="storeId">
          <el-select
            v-model="form.storeId"
            placeholder="选择门店"
            filterable
            clearable
            @change="onStoreChange"
          >
            <el-option
              v-for="s in stores"
              :key="s.id"
              :label="s.name"
              :value="s.id"
            />
          </el-select>
        </el-form-item>

        <!-- 分类 -->
        <el-form-item label="分类" prop="categoryId">
          <el-cascader
            v-model="form.categoryPath"
            :options="categoryOptions"
            placeholder="选择分类"
            clearable
            @change="onFormCategoryChange"
          />
        </el-form-item>

        <!-- 品牌 -->
        <el-form-item label="品牌" prop="brandId">
          <el-select
            v-model="form.brandId"
            placeholder="选择品牌"
            filterable
            clearable
          >
            <el-option
              v-for="b in brands"
              :key="b.id"
              :label="b.name"
              :value="b.id"
            />
          </el-select>
        </el-form-item>

        <!-- 名称 -->
        <el-form-item label="名称" prop="name">
          <el-input v-model="form.name" autocomplete="off" />
        </el-form-item>

        <!-- 描述 -->
        <el-form-item label="描述" prop="description">
          <el-input
            type="textarea"
            v-model="form.description"
            placeholder="可选"
          />
        </el-form-item>

        <!-- 主图上传 -->
        <el-form-item label="主图" prop="mainImage">
          <ImageUploadCropper
            v-model:imageUrl="form.mainImage"
            :aspect-ratio="'1:1'"
            :width="120"
            :height="120"
            tips="建议上传1:1比例的图片"
          />
        </el-form-item>

        <!-- 商品多图上传 -->
        <el-form-item label="商品多图">
          <div class="image-upload-list">
            <div
              v-for="(image, index) in form.images"
              :key="index"
              class="image-upload-item"
            >
              <ImageUploadCropper
                v-model:imageUrl="form.images[index]"
                :aspect-ratio="'1:1'"
                :width="100"
                :height="100"
                tips="建议上传1:1比例的图片"
                @remove="removeImage(index)"
              />
            </div>
            <el-button
              v-if="form.images.length < 5"
              type="primary"
              :icon="Plus"
              circle
              @click="addImage"
              class="add-image-btn"
            />
          </div>
          <p class="el-upload__tip">最多可上传5张商品多图</p>
        </el-form-item>

        <!-- 状态 -->
        <el-form-item label="状态" prop="status">
          <el-select v-model="form.status" placeholder="选择状态">
            <el-option label="启用" :value="1" />
            <el-option label="禁用" :value="0" />
          </el-select>
        </el-form-item>

        <!-- 添加SPU选择 -->
        <el-form-item label="SPU" prop="spuId">
          <el-select
            v-model="form.spuId"
            placeholder="选择SPU(可选)"
            filterable
            clearable
            @change="onSpuChange"
          >
            <el-option
              v-for="spu in spuOptions"
              :key="spu.id"
              :label="spu.title"
              :value="spu.id"
            />
          </el-select>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="dialogLoading" @click="submitForm">
          确定
        </el-button>
      </template>
    </el-dialog>

    <!-- 标签管理对话框 -->
    <el-dialog
      title="商品标签管理"
      v-model="tagDialogVisible"
      width="500px"
      destroy-on-close
    >
      <div class="tag-management">
        <div class="tag-list">
          <div class="tag-list-header">
            <span class="title">已选标签</span>
            <el-button type="primary" link @click="handleSelectAllTags">全选</el-button>
          </div>
          <div class="tag-list-content">
            <el-tag
              v-for="tag in selectedTags"
              :key="tag.id"
              class="tag-item"
              closable
              @close="handleRemoveTag(tag)"
            >
              {{ tag.name }}
            </el-tag>
            <el-empty v-if="selectedTags.length === 0" description="暂无标签" />
          </div>
        </div>

        <div class="tag-selector">
          <div class="tag-selector-header">
            <span class="title">可选标签</span>
            <el-input
              v-model="tagSearchKeyword"
              placeholder="搜索标签"
              clearable
              class="tag-search"
            >
              <template #prefix>
                <el-icon><Search /></el-icon>
              </template>
            </el-input>
          </div>
          <div class="tag-selector-content">
            <el-checkbox-group v-model="selectedTagIds">
              <el-checkbox
                v-for="tag in filteredTags"
                :key="tag.id"
                :label="tag.id"
                class="tag-checkbox"
              >
                {{ tag.name }}
              </el-checkbox>
            </el-checkbox-group>
            <el-empty v-if="filteredTags.length === 0" description="暂无标签" />
          </div>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="tagDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSaveTags">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 列设置弹窗 -->
    <el-dialog
      title="列设置"
      v-model="columnSettingsVisible"
      width="400px"
      destroy-on-close
    >
      <el-checkbox-group v-model="visibleColumns">
        <el-checkbox
          v-for="col in columnOptions"
          :key="col.prop"
          :label="col.prop"
        >
          {{ col.label }}
        </el-checkbox>
      </el-checkbox-group>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="columnSettingsVisible = false">取消</el-button>
          <el-button type="primary" @click="saveColumnSettings">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </el-card>
</template>
  
<script setup>
import { ref, reactive, onMounted, nextTick, computed } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  pageProducts,
  getProductDetail,
  addProduct,
  updateProduct,
  deleteProducts,
  updateProductStatus,
  pageStores,
  categoryTree,
  pageBrands,
  uploadFile,
  downloadProductTemplate,
  exportProducts,
  importProducts,
  batchUpdateStatus,
} from "@/api/products";
import { 
  listTagsByProduct, 
  assignTags, 
  removeTags 
} from '@/api/productTags';
import { pageTags } from '@/api/tags';
import { Search, Plus, Edit, Delete, PriceTag, Refresh, Setting, ArrowDown } from "@element-plus/icons-vue";
import { pageSpu } from "@/api/productSpu";
import ImageUploadCropper from "@/components/ImageUploadCropper.vue";

// 列表状态
const loading = ref(false);
const products = ref([]);
const total = ref(0);
const pageNum = ref(1);
const pageSize = ref(10);
const multipleSelection = ref([]);

// 过滤条件
const filters = reactive({
  name: "",
  status: null,
  storeId: null,
  categoryPath: [], // 级联选择的数组
  brandId: null,
});

// 下拉选项数据
const stores = ref([]);
const categoryOptions = ref([]);
const brands = ref([]);
const spuOptions = ref([]);

// 弹窗 & 表单
const dialogVisible = ref(false);
const dialogTitle = ref("新增商品");
const dialogLoading = ref(false);
const formRef = ref(null);
const form = reactive({
  id: null,
  storeId: null,
  categoryPath: [],
  categoryId: null,
  brandId: null,
  name: "",
  description: "",
  mainImage: "",
  status: 1,
  spuId: null,
  images: [],
});

// 表单校验规则
const formRules = {
  storeId: [{ required: true, message: "请选择门店", trigger: "change" }],
  categoryId: [{ required: true, message: "请选择分类", trigger: "change" }],
  brandId: [{ required: true, message: "请选择品牌", trigger: "change" }],
  name: [
    { required: true, message: "请输入商品名称", trigger: "blur" },
    { min: 1, max: 100, message: "长度 1-100", trigger: "blur" },
  ],
  status: [{ required: true, message: "请选择状态", trigger: "change" }],
};

// 标签管理相关
const tagDialogVisible = ref(false);
const currentProduct = ref(null);
const selectedTags = ref([]);
const allTags = ref([]);
const selectedTagIds = ref([]);
const tagSearchKeyword = ref('');

// 过滤后的标签列表
const filteredTags = computed(() => {
  if (!tagSearchKeyword.value) return allTags.value;
  return allTags.value.filter(tag => 
    tag.name.toLowerCase().includes(tagSearchKeyword.value.toLowerCase())
  );
});

// 列设置相关
const columnSettingsVisible = ref(false)
const visibleColumns = ref([])
const columnOptions = [
  { prop: 'storeName', label: '门店' },
  { prop: 'categoryName', label: '分类' },
  { prop: 'brand', label: '品牌' },
  { prop: 'name', label: '商品名称' },
  { prop: 'spuTitle', label: 'SPU' },
  { prop: 'mainImage', label: '主图' },
  { prop: 'status', label: '状态' },
  { prop: 'createdAt', label: '创建时间' }
]

onMounted(async () => {
  loadStores();
  loadCategories();
  loadBrands();
  loadSpus();
  fetchList();

  // 优先从本地存储加载列设置
  const savedColumns = localStorage.getItem('productColumns')
  console.log('onMounted - 从本地存储读取到的数据:', savedColumns)

  if (savedColumns) {
    try {
      const parsedColumns = JSON.parse(savedColumns)
      visibleColumns.value = parsedColumns
      console.log('onMounted - 成功解析本地存储数据，visibleColumns:', visibleColumns.value)
    } catch (e) {
      console.error("onMounted - 解析本地存储的列设置失败", e)
      // 解析失败则使用默认值
      visibleColumns.value = columnOptions.map(col => col.prop)
      console.log('onMounted - 解析失败，使用默认列:', visibleColumns.value)
    }
  } else {
    // 如果本地存储没有，则默认显示所有列
    visibleColumns.value = columnOptions.map(col => col.prop)
    console.log('onMounted - 本地存储为空，使用默认列:', visibleColumns.value)
  }
});

// 加载门店（用于筛选和表单）
async function loadStores() {
  try {
    const res = await pageStores({ pageNum: 1, pageSize: 100 });
    stores.value = res.data.items || [];
  } catch (err) {
    console.error("获取门店失败", err);
  }
}

// 加载分类树
async function loadCategories() {
  try {
    const res = await categoryTree();
    const convert = (list) => {
      return list.map((item) => {
        const node = {
          value: item.id,
          label: item.name,
        };
        if (item.children && item.children.length) {
          node.children = convert(item.children);
        }
        return node;
      });
    };
    categoryOptions.value = convert(res.data || res.data.items || []);
  } catch (err) {
    console.error("获取分类树失败", err);
  }
}

// 加载品牌列表
async function loadBrands() {
  try {
    const res = await pageBrands({
      pageNum: 1,
      pageSize: 100,
      name: "",
      status: null,
    });
    brands.value = res.data.items || [];
  } catch (err) {
    console.error("获取品牌失败", err);
  }
}

// 加载SPU列表
async function loadSpus() {
  try {
    const res = await pageSpu({
      pageNum: 1,
      pageSize: 100,
      title: "",
      saleable: null,
    });
    spuOptions.value = res.data.items || [];
  } catch (err) {
    console.error("获取SPU列表失败", err);
  }
}

// 列表查询
async function fetchList() {
  loading.value = true;
  try {
    // 取 categoryPath 最后一项为 categoryId
    const categoryId =
      filters.categoryPath && filters.categoryPath.length
        ? filters.categoryPath[filters.categoryPath.length - 1]
        : null;

    const params = {
      pageNum: pageNum.value,
      pageSize: pageSize.value,
      ...(filters.name ? { name: filters.name } : {}),
      ...(filters.status !== null ? { status: filters.status } : {}),
      ...(filters.storeId ? { storeId: filters.storeId } : {}),
      ...(categoryId ? { categoryId } : {}),
      ...(filters.brandId ? { brandId: filters.brandId } : {}),
    };
    const res = await pageProducts(params);
    const data = res.data;
    products.value = data.items || [];
    total.value = data.total || 0;
  } catch (err) {
    console.error("查询商品失败", err);
  } finally {
    loading.value = false;
  }
}

// 分页回调
function onPageChange(page) {
  pageNum.value = page;
  fetchList();
}
function onSizeChange(size) {
  pageSize.value = size;
  pageNum.value = 1;
  fetchList();
}

// 选择行
function onSelectChange(val) {
  multipleSelection.value = val;
}

// 搜索按钮
function onSearch() {
  pageNum.value = 1;
  fetchList();
}

// 当分类筛选器变化时
function onCategoryChange(val) {
  filters.categoryPath = val || [];
  pageNum.value = 1;
  fetchList();
}

// 打开新增/编辑弹窗
async function openDialog(row) {
  if (row) {
    // 编辑
    dialogTitle.value = "编辑商品";
    dialogLoading.value = false;
    // 载入详情
    try {
      const res = await getProductDetail(row.id);
      const d = res.data;
      form.id = d.id;
      form.storeId = d.storeId;
      // 找到 categoryPath（完整路径）
      form.categoryPath = findCategoryPath(
        d.categoryId,
        categoryOptions.value
      ) || [d.categoryId];
      form.categoryId = d.categoryId;
      form.brandId = d.brandId;
      form.name = d.name;
      form.description = d.description;
      form.mainImage = d.mainImage;
      form.status = d.status;
      form.spuId = d.spuId;

      // 直接赋值 images 数组，后端已返回正确格式
      form.images = d.images || [];

    } catch (err) {
      console.error("获取商品详情失败", err);
    }
    dialogVisible.value = true;
  } else {
    // 新增
    dialogTitle.value = "新增商品";
    formRef.value?.resetFields(); // 重置表单
    form.id = null;
    form.storeId = null;
    form.categoryPath = [];
    form.categoryId = null;
    form.brandId = null;
    form.name = "";
    form.description = "";
    form.mainImage = "";
    form.images = []; // 新增时清空图片数组
    form.status = 1;
    form.spuId = null;
    await nextTick();
    dialogVisible.value = true;
  }
}

// 辅助：根据 categoryOptions 构建 id->path 映射（递归查找 path）
function findCategoryPath(targetId, options, path = []) {
  for (const node of options) {
    const newPath = [...path, node.value];
    if (node.value === targetId) {
      return newPath;
    }
    if (node.children) {
      const res = findCategoryPath(targetId, node.children, newPath);
      if (res) return res;
    }
  }
  return null;
}

// 当表单中分类级联变化时，更新 form.categoryId
function onFormCategoryChange(val) {
  form.categoryId = val && val.length ? val[val.length - 1] : null;
}

// 当表单中门店变化时
function onStoreChange(val) {
  // 如有需要可在此做联动
}

// 提交表单
function submitForm() {
  formRef.value.validate(async (valid) => {
    if (!valid) return;
    dialogLoading.value = true;
    try {
      console.log("Form images before submission:", form.images);
      const payload = {
        ...(form.id ? { id: form.id } : {}),
        storeId: form.storeId,
        categoryId: form.categoryId,
        brandId: form.brandId,
        name: form.name,
        description: form.description,
        mainImage: form.mainImage,
        status: form.status,
        spuId: form.spuId,
        images: JSON.stringify(form.images),
      };
      if (form.id) {
        await updateProduct(payload);
        ElMessage.success("更新成功");
      } else {
        await addProduct(payload);
        ElMessage.success("新增成功");
      }
      dialogVisible.value = false;
      fetchList();
    } catch (err) {
      console.error("保存商品失败", err);
    } finally {
      dialogLoading.value = false;
    }
  });
}

// 删除单条
function onDelete(row) {
  ElMessageBox.confirm("确认删除该商品？", "提示", { type: "warning" }).then(
    async () => {
      try {
        await deleteProducts([row.id].join(","));
        ElMessage.success("删除成功");
        fetchList();
      } catch (err) {
        console.error("删除失败", err);
      }
    }
  );
}

// 批量删除
function onBatchDelete() {
  const ids = multipleSelection.value.map((item) => item.id);
  if (!ids.length) return;
  ElMessageBox.confirm(`确认删除选中的 ${ids.length} 条？`, "提示", {
    type: "warning",
  }).then(async () => {
    try {
      await deleteProducts(ids.join(","));
      ElMessage.success("批量删除成功");
      multipleSelection.value = [];
      fetchList();
    } catch (err) {
      console.error("批量删除失败", err);
    }
  });
}

// 切换状态
async function onToggleStatus(row, newStatus) {
  try {
    await updateProductStatus(row.id, newStatus);
    ElMessage.success("状态更新成功");
  } catch (err) {
    row.status = newStatus === 1 ? 0 : 1;
    console.error("状态更新失败", err);
  }
}

// 图片上传处理
async function handleUploadRequest(option) {
  const formData = new FormData();
  formData.append("file", option.file);
  try {
    const res = await uploadFile(formData);
    const url = res.data;
    form.mainImage = url;
    option.onSuccess(res.data);
    ElMessage.success("上传成功");
  } catch (err) {
    console.error("上传失败", err);
    option.onError(err);
    ElMessage.error("上传失败");
  }
}

// 上传前校验
function beforeUpload(file) {
  const isImage = file.type.startsWith("image/");
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isImage) {
    ElMessage.error("上传文件须为图片");
  }
  if (!isLt2M) {
    ElMessage.error("上传图片大小不能超过 2MB");
  }
  return isImage && isLt2M;
}


// 下载模板
async function downloadTemplate() {
  try {
    const res = await downloadProductTemplate(); // axios 要设置 responseType: 'blob'
    // 假设 API 调用已在 axios 中配置 responseType
    const blob = new Blob([res], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "商品导入模板.xlsx";
    a.click();
    window.URL.revokeObjectURL(url);
  } catch (err) {
    console.error("下载模板失败", err);
    ElMessage.error("下载模板失败");
  }
}

// 导出当前筛选商品
async function exportAll() {
  try {
    // 也可以传当前 filters 作为查询参数，后端按条件导出；这里示例按当前 filters 导出：
    const categoryId =
      filters.categoryPath && filters.categoryPath.length
        ? filters.categoryPath[filters.categoryPath.length - 1]
        : null;
    const params = {
      ...(filters.name ? { name: filters.name } : {}),
      ...(filters.status !== null ? { status: filters.status } : {}),
      ...(filters.storeId ? { storeId: filters.storeId } : {}),
      ...(categoryId ? { categoryId } : {}),
      ...(filters.brandId ? { brandId: filters.brandId } : {}),
    };
    // 假设 exportProducts 接口支持接收查询参数，如 GET /export?name=...&storeId=...
    const res = await exportProducts({ params, responseType: "blob" });
    // 若使用 axios，需在调用时指定 responseType: 'blob'，或在 api 方法中统一设置
    const blob = new Blob([res], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "商品列表.xlsx";
    a.click();
    window.URL.revokeObjectURL(url);
  } catch (err) {
    console.error("导出失败", err);
    ElMessage.error("导出失败");
  }
}

// 导入前拦截
function beforeImport(file) {
  // 限制类型 & 大小，可按需修改
  const isExcel = file.name.endsWith(".xls") || file.name.endsWith(".xlsx");
  const isLt5M = file.size / 1024 / 1024 < 5;
  if (!isExcel) {
    ElMessage.error("请上传 Excel 文件");
    return false;
  }
  if (!isLt5M) {
    ElMessage.error("文件大小不能超过 5MB");
    return false;
  }
  // 构造 FormData 并调用 importProducts
  const formData = new FormData();
  formData.append("file", file);
  importProducts(formData)
    .then(() => {
      ElMessage.success("导入成功");
      // 导入完成后刷新列表
      pageNum.value = 1;
      fetchList();
    })
    .catch((err) => {
      console.error("导入失败", err);
      ElMessage.error("导入失败");
    });
  // 返回 false 阻止 el-upload 自动上传
  return false;
}

// 打开标签管理对话框
const openTagDialog = async (row) => {
  currentProduct.value = row;
  tagDialogVisible.value = true;
  try {
    // 获取商品已关联的标签
    const res = await listTagsByProduct(row.id);
    selectedTags.value = res.data.tags || [];
    selectedTagIds.value = selectedTags.value.map(tag => tag.id);
    
    // 获取所有可用标签
    const tagsRes = await pageTags({pageNum: 1, pageSize: 100});
    allTags.value = tagsRes.data.items || [];
  } catch (error) {
    console.error('获取标签失败:', error);
    ElMessage.error('获取标签失败');
  }
};

// 移除标签
const handleRemoveTag = async (tag) => {
  try {
    await removeTags({
      productId: currentProduct.value.id,
      tagIds: [tag.id]
    });
    selectedTags.value = selectedTags.value.filter(t => t.id !== tag.id);
    selectedTagIds.value = selectedTagIds.value.filter(id => id !== tag.id);
    ElMessage.success('移除标签成功');
  } catch (error) {
    console.error('移除标签失败:', error);
    ElMessage.error('移除标签失败');
  }
};

// 全选标签
const handleSelectAllTags = () => {
  selectedTagIds.value = allTags.value.map(tag => tag.id);
};

// 保存标签
const handleSaveTags = async () => {
  if (!currentProduct.value) return;
  
  try {
    // 获取需要新增的标签ID
    const newTagIds = selectedTagIds.value.filter(
      id => !selectedTags.value.some(tag => tag.id === id)
    );
    
    // 获取需要移除的标签ID
    const removeTagIds = selectedTags.value
      .filter(tag => !selectedTagIds.value.includes(tag.id))
      .map(tag => tag.id);
    
    // 执行标签分配和移除
    if (newTagIds.length > 0) {
      await assignTags({
        productId: currentProduct.value.id,
        tagIds: newTagIds
      });
    }
    
    if (removeTagIds.length > 0) {
      await removeTags({
        productId: currentProduct.value.id,
        tagIds: removeTagIds
      });
    }
    
    ElMessage.success('保存标签成功');
    tagDialogVisible.value = false;
  } catch (error) {
    console.error('保存标签失败:', error);
    ElMessage.error('保存标签失败');
  }
};

// 添加SPU选择变化的处理方法
function onSpuChange(val) {
  form.spuId = val;
}

// 显示列设置
const showColumnSettings = () => {
  columnSettingsVisible.value = true
}

// 保存列设置
const saveColumnSettings = () => {
  console.log('saveColumnSettings - 准备保存的 visibleColumns:', visibleColumns.value)
  // 保存到本地存储
  localStorage.setItem('productColumns', JSON.stringify(visibleColumns.value))
  console.log('saveColumnSettings - 数据已保存到本地存储')
  columnSettingsVisible.value = false
  nextTick(() => {
    // 可以在这里触发表格的 layout 刷新，以防万一
  })
}

// 刷新数据
const onRefresh = () => {
  fetchList()
}

// 排序变化
const onSortChange = ({ prop, order }) => {
  // 实现排序逻辑
  console.log('Sort changed:', prop, order)
}

// 批量操作
const handleBatchCommand = async (command) => {
  if (!multipleSelection.value.length) {
    ElMessage.warning('请选择要操作的商品')
    return
  }

  try {
    const ids = multipleSelection.value.map(item => item.id)
    switch (command) {
      case 'enable':
        await ElMessageBox.confirm('确定要启用选中的商品吗？', '提示', {
          type: 'warning'
        })
        await batchUpdateStatus({ ids, status: 1 })
        ElMessage.success('批量启用成功')
        break
      case 'disable':
        await ElMessageBox.confirm('确定要禁用选中的商品吗？', '提示', {
          type: 'warning'
        })
        await batchUpdateStatus({ ids, status: 0 })
        ElMessage.success('批量禁用成功')
        break
    }
    // 刷新数据
    fetchList()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('操作失败：' + (error.message || '未知错误'))
    }
  }
}

// 导出命令
const handleExportCommand = (command) => {
  if (command === 'excel') {
    exportAll('excel')
  }
}

// 添加图片
const addImage = () => {
  form.images.push('');
}

// 移除图片
const removeImage = (index) => {
  form.images.splice(index, 1);
}
</script>
  
<style scoped>
.products-page {
  padding: 32px 16px 24px 16px;
  background: linear-gradient(135deg, #f8fafc 0%, #f0f4f8 100%);
  border-radius: 18px;
  box-shadow: 0 6px 32px 0 rgba(80,120,200,0.08);
  min-height: 90vh;
  transition: box-shadow 0.3s;
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 24px;
  background: rgba(255,255,255,0.85);
  border-radius: 14px;
  box-shadow: 0 2px 12px 0 rgba(80,120,200,0.06);
  padding: 18px 18px 10px 18px;
  animation: fadeInDown 0.7s;
}

@keyframes fadeInDown {
  from { opacity: 0; transform: translateY(-20px); }
  to { opacity: 1; transform: none; }
}

.toolbar-item {
  width: auto;
  min-width: 120px;
  transition: box-shadow 0.2s, border-color 0.2s;
}
.toolbar-item .el-input__wrapper,
.toolbar-item .el-select__wrapper {
  border-radius: 8px;
  box-shadow: 0 1px 4px 0 rgba(80,120,200,0.04);
}
.toolbar-item .el-input__wrapper:hover,
.toolbar-item .el-select__wrapper:hover {
  border-color: #6c8cff;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
}

.toolbar-actions {
  margin-left: auto;
  display: flex;
  gap: 10px;
  align-items: center;
}
.toolbar-actions .el-button {
  border-radius: 50%;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
  transition: background 0.2s, box-shadow 0.2s, transform 0.2s;
}
.toolbar-actions .el-button:hover {
  background: linear-gradient(90deg, #6c8cff 0%, #88e0ef 100%);
  color: #fff;
  transform: scale(1.08);
}

.el-button[type="primary"] {
  background: linear-gradient(90deg, #6c8cff 0%, #88e0ef 100%);
  border: none;
  color: #fff;
  font-weight: 500;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
  transition: background 0.2s, box-shadow 0.2s;
}
.el-button[type="primary"]:hover {
  background: linear-gradient(90deg, #88e0ef 0%, #6c8cff 100%);
  color: #fff;
}

.el-button[type="danger"] {
  background: linear-gradient(90deg, #ff6c6c 0%, #ffb88c 100%);
  border: none;
  color: #fff;
  font-weight: 500;
  box-shadow: 0 2px 8px 0 rgba(255,108,108,0.10);
  transition: background 0.2s, box-shadow 0.2s;
}
.el-button[type="danger"]:hover {
  background: linear-gradient(90deg, #ffb88c 0%, #ff6c6c 100%);
  color: #fff;
}

.pagination {
  text-align: center;
  margin-top: 24px;
}
.el-pagination {
  border-radius: 10px;
  background: rgba(255,255,255,0.85);
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.06);
  padding: 8px 16px;
}

.table-wrapper {
  margin: 20px 0;
  border-radius: 8px;
  background: #fff;
  padding: 0;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  width: 100%;
  overflow: hidden;
}

:deep(.el-table) {
  width: 100%;
  min-width: 1200px;
  border-radius: 8px;
  overflow: hidden;
}

:deep(.el-table__body-wrapper) {
  overflow-x: auto !important;
  overflow-y: auto !important;
}

:deep(.el-table__body) {
  /* Removed explicit width/min-width here; let columns dictate total width */
}

:deep(.el-table--border) {
  border-radius: 8px;
  overflow: hidden;
}

:deep(.el-table__fixed-right) {
  height: 100% !important;
  right: 0;
  box-shadow: -6px 0 6px -4px rgba(0, 0, 0, 0.12);
}

:deep(.el-table__fixed) {
  height: 100% !important;
  left: 0;
  box-shadow: 6px 0 6px -4px rgba(0, 0, 0, 0.12);
}

:deep(.el-table__body-wrapper::-webkit-scrollbar) {
  width: 8px;
  height: 10px;
  display: block !important;
}

:deep(.el-table__body-wrapper::-webkit-scrollbar-thumb) {
  background: #dcdfe6;
  border-radius: 4px;
}

:deep(.el-table__body-wrapper::-webkit-scrollbar-track) {
  background: #f5f7fa;
}

.el-table {
  border-radius: 14px;
  overflow: hidden;
  background: rgba(255,255,255,0.98);
  box-shadow: 0 2px 16px 0 rgba(80,120,200,0.07);
  animation: fadeIn 0.7s;
}
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
.el-table th {
  background: linear-gradient(90deg, #f0f4ff 0%, #f8fafc 100%);
  color: #4a5a7a;
  font-weight: 600;
  font-size: 15px;
}
.el-table tr {
  transition: background 0.2s;
}
.el-table tr:hover {
  background: #eaf3ff !important;
}
.el-table .el-table__row.selected {
  background: #d6e4ff !important;
}
.el-table .el-button {
  border-radius: 50%;
  font-size: 18px;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 2px;
  box-shadow: 0 1px 4px 0 rgba(80,120,200,0.08);
  transition: background 0.2s, transform 0.2s;
}
.el-table .el-button:hover {
  background: linear-gradient(90deg, #6c8cff 0%, #88e0ef 100%);
  color: #fff;
  transform: scale(1.12);
}
.el-table .el-image {
  border-radius: 10px;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
  border: 1.5px solid #e4e7ed;
  background: #fff;
}

.image-preview img {
  border: 2px solid #e4e7ed;
  border-radius: 8px;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
}

.el-dialog {
  border-radius: 18px !important;
  box-shadow: 0 8px 40px 0 rgba(80,120,200,0.18) !important;
  animation: fadeInUp 0.5s;
}
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(40px); }
  to { opacity: 1; transform: none; }
}
.el-dialog__header {
  font-size: 22px;
  font-weight: 700;
  color: #3a4a6a;
  letter-spacing: 1px;
}
.el-dialog__footer {
  background: #f8fafc;
  border-radius: 0 0 18px 18px;
  padding: 18px 24px;
}
.el-form-item__label {
  font-weight: 600;
  color: #3a4a6a;
  font-size: 15px;
}
.el-form-item .el-input__wrapper,
.el-form-item .el-select__wrapper,
.el-form-item .el-cascader__wrapper {
  border-radius: 8px;
  box-shadow: 0 1px 4px 0 rgba(80,120,200,0.04);
  transition: box-shadow 0.2s, border-color 0.2s;
}
.el-form-item .el-input__wrapper:focus-within,
.el-form-item .el-select__wrapper:focus-within,
.el-form-item .el-cascader__wrapper:focus-within {
  border-color: #6c8cff;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
}
.el-upload .el-button {
  border-radius: 8px;
  background: linear-gradient(90deg, #6c8cff 0%, #88e0ef 100%);
  color: #fff;
  font-weight: 500;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
}
.el-upload .el-button:hover {
  background: linear-gradient(90deg, #88e0ef 0%, #6c8cff 100%);
}

/* 标签管理相关样式 */
.tag-management {
  display: flex;
  flex-direction: column;
  gap: 24px;
  animation: fadeIn 0.7s;
}

.tag-list,
.tag-selector {
  border: 1.5px solid #e4e7ed;
  border-radius: 12px;
  padding: 18px;
  background: linear-gradient(135deg, #f8fafc 0%, #f0f4f8 100%);
  box-shadow: 0 2px 12px 0 rgba(80,120,200,0.06);
}

.tag-list-header,
.tag-selector-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.tag-list-header .title,
.tag-selector-header .title {
  font-size: 17px;
  font-weight: 600;
  color: #3a4a6a;
}

.tag-search {
  width: 220px;
  border-radius: 8px;
  box-shadow: 0 1px 4px 0 rgba(80,120,200,0.04);
  transition: box-shadow 0.2s, border-color 0.2s;
}
.tag-search .el-input__wrapper {
  border-radius: 8px;
}

.tag-list-content {
  min-height: 60px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.tag-item {
  margin-right: 8px;
  margin-bottom: 8px;
  background: linear-gradient(90deg, #6c8cff 0%, #88e0ef 100%);
  color: #fff;
  font-weight: 500;
  border-radius: 8px;
  box-shadow: 0 1px 4px 0 rgba(80,120,200,0.10);
  transition: background 0.2s, transform 0.2s;
  cursor: pointer;
  padding: 4px 14px;
  font-size: 15px;
  animation: fadeInTag 0.5s;
}
@keyframes fadeInTag {
  from { opacity: 0; transform: scale(0.8); }
  to { opacity: 1; transform: none; }
}
.tag-item:hover {
  background: linear-gradient(90deg, #88e0ef 0%, #6c8cff 100%);
  transform: scale(1.08);
}

.tag-selector-content {
  min-height: 120px;
  max-height: 260px;
  overflow-y: auto;
  padding: 8px;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  background: #fff;
}

.tag-checkbox {
  display: block;
  margin-bottom: 8px;
  padding: 8px 12px;
  border-radius: 6px;
  transition: all 0.3s;
  font-size: 15px;
  font-weight: 500;
  color: #3a4a6a;
}
.tag-checkbox .el-checkbox__input.is-checked + .el-checkbox__label {
  color: #6c8cff;
}
.tag-checkbox:hover {
  background-color: #f5f7fa;
  color: #6c8cff;
}

.dialog-footer .el-button {
  min-width: 90px;
  border-radius: 8px;
  font-weight: 500;
  font-size: 15px;
}
.dialog-footer .el-button[type="primary"] {
  background: linear-gradient(90deg, #6c8cff 0%, #88e0ef 100%);
  color: #fff;
}
.dialog-footer .el-button[type="primary"]:hover {
  background: linear-gradient(90deg, #88e0ef 0%, #6c8cff 100%);
}

/* 响应式调整 */
@media screen and (max-width: 1024px) {
  .products-page {
    padding: 8px 2px 12px 2px;
  }
  .toolbar {
    flex-direction: column;
    gap: 10px;
    padding: 12px 8px 6px 8px;
  }
  .toolbar-actions {
    margin-left: 0;
    justify-content: flex-start;
  }
  .el-table th, .el-table td {
    font-size: 13px;
  }
}
@media screen and (max-width: 768px) {
  .products-page {
    padding: 2px 0 6px 0;
    min-height: unset;
  }
  .toolbar {
    flex-direction: column;
    gap: 8px;
    padding: 8px 2px 4px 2px;
  }
  .toolbar-item, .tag-search {
    min-width: 90px;
    width: 100%;
  }
  .el-table th, .el-table td {
    font-size: 12px;
    padding: 4px 2px;
  }
  .el-dialog {
    width: 98vw !important;
    min-width: unset;
    padding: 0;
  }
  .tag-management {
    gap: 10px;
  }
  .tag-list, .tag-selector {
    padding: 8px;
  }
}

.action-btns {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 14px; /* 按钮间距可根据需要调整 */
  min-width: 180px;
}

/* 列设置弹窗样式 */
:deep(.el-checkbox-group) {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

:deep(.el-checkbox) {
  margin-right: 0;
  height: 32px;
  line-height: 32px;
}

/* 表格列宽调整样式 */
:deep(.el-table__column-resize-proxy) {
  background-color: var(--el-color-primary);
}

/* 图片预览样式 */
:deep(.el-image-viewer__wrapper) {
  z-index: 2100;
}

/* 商品多图上传样式 */
.image-upload-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px; /* 图片间距 */
  align-items: flex-start;
}

.image-upload-item {
  position: relative;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.add-image-btn {
  width: 100px; /* 按钮大小 */
  height: 100px; /* 按钮大小 */
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 20px; /* 加号图标大小 */
  color: #8c939d;
  &:hover {
    border-color: var(--el-color-primary);
    color: var(--el-color-primary);
  }
}
</style>
  